import i18n from '@/i18n'
import { MetaResourceModelDao } from '@apps/meta/domain/meta-resource-model/meta-resource-model.dao'
import { MetaResourceModuleActionDao } from '@apps/meta/domain/meta-resource-module-action/meta-resource-module-action.dao'
import { MetaResourceModuleDao } from '@apps/meta/domain/meta-resource-module/meta-resource-module.dao'
import { DomainModel } from '@apps/meta/domain/model'
import { Assist } from '@libs/lhy-common'
import { Body, Controller, Delete, Post, Put, Query } from '@nestjs/common'
import { ApiOperation, ApiTags } from '@nestjs/swagger'
import { MetaResourceModelService } from '../meta-resource-model/meta-resource-model.service'
import { MetaResourceModuleActionListDto } from './dto/meta-resource-module-action-list.dto'
import { MetaResourceModuleActionSaveDto } from './dto/meta-resource-module-action-save.dto'
import { MetaResourceModuleActionUpdateByIdDto } from './dto/meta-resource-module-action-update-by-id.dto'

@ApiTags(i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-0'))
@Controller({
  path: 'resource_module_action',
  version: '1',
})
export class MetaResourceModuleActionController {
  constructor(
    private readonly resourceModuleActionDao: MetaResourceModuleActionDao,
    private readonly resourceModuleDao: MetaResourceModuleDao,
    private readonly resourceModelDao: MetaResourceModelDao,
    private readonly resourceModelService: MetaResourceModelService
  ) {}

  @ApiOperation({ summary: i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-1') })
  @Post('list')
  list(@Body() param: MetaResourceModuleActionListDto) {
    return this.resourceModuleActionDao.list({
      platform: param.platform,
      resourceModuleName: param.resourceModuleName,
      label: {
        contains: param.label,
      },
      actionType: {
        in: param.actionTypes,
      },
    })
  }

  @ApiOperation({ summary: i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-2') })
  @Put()
  async save(@Body() param: MetaResourceModuleActionSaveDto): Promise<void> {
    const resourceModule = Assist.notNull(
      await this.resourceModuleDao.getById(param.resourceModuleId),
      i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-3', {
        args: [param.resourceModuleId],
      })
    )
    Assist.threw(
      await this.resourceModuleActionDao.isNameExists({
        platform: param.platform,
        resourceModuleId: param.resourceModuleId,
        name: param.name,
      }),
      i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-4', { args: [param.name] })
    )
    Assist.threw(
      await this.resourceModuleActionDao.isLabelExists({
        platform: param.platform,
        resourceModuleId: param.resourceModuleId,
        label: param.label,
      }),
      i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-5', { args: [param.label] })
    )

    const requestModels = this.resourceModelService.buildBatchSaveModels(param.requestModels || [], {
      type: DomainModel.MetaResourceModelType.Request,
      relativeType: DomainModel.MetaResourceRelativeType.ModuleAction,
      relativeId: -1,
    })
    const responseModels = this.resourceModelService.buildBatchSaveModels(param.requestModels || [], {
      type: DomainModel.MetaResourceModelType.Response,
      relativeType: DomainModel.MetaResourceRelativeType.ModuleAction,
      relativeId: -1,
    })

    const newData = await this.resourceModuleActionDao.save({ ...param, resourceModuleName: resourceModule.name })

    // 添加模型
    if (requestModels.length || responseModels.length) {
      await this.resourceModelDao.batchSave([
        ...requestModels.map(model => ({ ...model, relativeId: newData.id })),
        ...responseModels.map(model => ({ ...model, relativeId: newData.id })),
      ])
    }
  }

  @ApiOperation({ summary: i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-6') })
  @Post()
  async updateById(@Body() param: MetaResourceModuleActionUpdateByIdDto): Promise<void> {
    const oldData = Assist.notNull(
      await this.resourceModuleActionDao.getById(param.id),
      i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-7', { args: [param.id] })
    )

    Assist.threw(
      await this.resourceModuleActionDao.isLabelExists({
        platform: oldData.platform,
        resourceModuleId: oldData.resourceModuleId,
        label: param.label,
        id: param.id,
      }),
      i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-5', { args: [param.label] })
    )

    const requestModels = this.resourceModelService.buildBatchSaveModels(param.requestModels || [], {
      type: DomainModel.MetaResourceModelType.Request,
      relativeType: DomainModel.MetaResourceRelativeType.ModuleAction,
      relativeId: param.id,
    })
    const responseModels = this.resourceModelService.buildBatchSaveModels(param.responseModels || [], {
      type: DomainModel.MetaResourceModelType.Response,
      relativeType: DomainModel.MetaResourceRelativeType.ModuleAction,
      relativeId: param.id,
    })

    await Promise.all([
      // 更新数据
      this.resourceModuleActionDao.updateById(param.id, param),
      // 删除关联模型
      this.resourceModelDao.deleteByRelative({
        relativeType: DomainModel.MetaResourceRelativeType.ModuleAction,
        relativeId: param.id,
      }),
    ])

    // 添加新模型
    if (requestModels.length || responseModels.length) {
      await this.resourceModelDao.batchSave(requestModels.concat(responseModels))
    }
  }

  @ApiOperation({ summary: i18n.t('app-meta.meta-resource-module-action.meta-resource-module-action.12150117-8') })
  @Delete()
  async deleteById(@Query('id') id: number): Promise<void> {
    await this.resourceModuleActionDao.deleteById(id, true)
  }
}
